/*******************************************************************************
filename      CVector.h
author        Craig Williams

Brief Description:
  dll safe container, similar to std::vector; however, it does several things
    differently.

  Highlights:
    erase()   - erase() does not preserve sort order. Rather, the last element
                  is used to overwrite the element that is being erased. This
                  is drastically faster then shifting over all the elements
                  after the erased object.
    raw copy  - When elements are shifted/moved around, a raw copy is
                  performed. std::vector will call the copy constructor and
                  destructor for all elements that move. This is extremely
                  slow, especially when the vector needs to grow.
                This can be dangerious if there is a pointer to a element inside
                  a vector, or a element stores a pointer to it's self; however,
                  those cases are extremely rare and generally a bad idea to
                  begin with.
    realloc() - This class uses the *alloc() family. realloc() can perform
                  optimizations at the kernel level (just expand the memory)
                  that you cannot do with new/delete. As such, in it's best
                  case, it'll be extrmely faster. In the worst case, it'll be
                  the same as new/delete.
*******************************************************************************/
#ifndef CVECTOR_H
#define CVECTOR_H

#define CVECTOR_BOUNDS_CHECKING 1

template<typename T>
class CVector
{
  public:
    CVector(int initsize = 10, float growth = 1.5f);
    CVector(const CVector<T> &vec);
    ~CVector();

    CVector &operator=(const CVector<T> &vec);

      // Insertion/Removal of elements
    void push_back (const T &data     );
    void push_last (void              ); // Basically push_back(back())
    void pop_back  (void              );
    void erase     (unsigned int index);

      // Accessors
    T   &operator[](unsigned int index) const;
    T   &at        (unsigned int index) const;
    T   &front     (void) const;
    T   &back      (void) const;

      // Capacity related
    unsigned int size    (void) const;
    unsigned int capacity(void) const;
    bool         empty   (void) const;

    void clear     (void);
    void reserve   (unsigned int size);
    void resize    (unsigned int size, T c = T());


     // Extensions
    CVector &operator+=(const CVector &r);
    CVector  operator+ (const CVector &r) const;

      // Extension - Dangerious. Increases the capactiy of the
      //   vector if required, and then changes Cur. No
      //   Copy Ctors or dtors are involked.
    void RawSetCur (unsigned int n_elems);

    T *mData;              // Actual Data

  protected:
    void AllocData(void); // Expands the array
    int   InitSize;       // Initial size of the array
    float Growth;         // Linear Growth Rate of the vector
    unsigned int Num;     // Number of elements the array can hold
    unsigned int Cur;     // Index + 1 of the last element in the array

    void *(*Realloc)(void *ptr, int size);
    void  (*Free)   (void *ptr);
};

#include "CVector.cpp"

#endif //CVECTOR_H
